package webservice;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import model.Host;
import model.Message;
import model.User;
import beans.ChatDataLocal;
import beans.UserSyncLocal;

@WebService(endpointInterface = "webservice.NodeCommunicationWS", serviceName = "NodeCommunication", targetNamespace = "http://1337.webservice")
@Stateless
@Remote(NodeCommunicationWS.class)
public class NodeCommunicationBean implements NodeCommunicationWS {

	@EJB
	private ChatDataLocal chatData;
	
	@EJB
	private UserSyncLocal userSync;
	
	@Resource(mappedName = "java:/ConnectionFactory")
	private ConnectionFactory connectionFactory;
    
    @Resource(mappedName = "java:/topic/mojTopic")
    private Topic topic;
	
	private NodeCommunicationWS service;
	
	@Override
	public ArrayList<Host> register(Host host) {
		// TODO Auto-generated method stub
		String httpHeader = chatData.getHttpHeader();
		String wsdlLocation = chatData.getWsdlLocation();
		QName serviceName = chatData.getServiceName();
		
		for(Host h : chatData.getHosts()) {
			if(!h.equals(chatData.getLocalHost())){
				
				try {
					Service temp = Service
							.create(new URL(httpHeader+h.getAddress()+wsdlLocation), serviceName);
					service = temp.getPort(NodeCommunicationWS.class);
					
					
					service.notifyRegister(host);

				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
				
			}
		}
		chatData.getHosts().add(host);
		
		return chatData.getHosts();
	}

	@Override
	public void notifyRegister(Host host) {
		// TODO Auto-generated method stub
		chatData.getHosts().add(host);
	}

	@Override
	public void unregister(Host host) {
		// TODO Auto-generated method stub
		String httpHeader = chatData.getHttpHeader();
		String wsdlLocation = chatData.getWsdlLocation();
		QName serviceName = chatData.getServiceName();
		
		for(Host h : chatData.getHosts())
			if(!h.equals(chatData.getLocalHost())){
				
				try {
					Service temp = Service
							.create(new URL(httpHeader+h.getAddress()+wsdlLocation), serviceName);
					service = temp.getPort(NodeCommunicationWS.class);
					
					
					service.notifyUnregister(host);

				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
				
			}
		
		chatData.getHosts().remove(host);
		
	}

	@Override
	public void notifyUnregister(Host host) {
		// TODO Auto-generated method stub
		chatData.getHosts().remove(host);
	}

	@Override
	public void updateUserList(List<User> usersFromHost) {
		// TODO Auto-generated method stub
		
		for(User u : usersFromHost) {
			if(chatData.getAllUsers().contains(u)) chatData.getAllUsers().remove(u);
			else chatData.getAllUsers().add(u);
		}
		userSync.syncWithClient(usersFromHost);
	}
	
	@Override
	public void updateUserList(User user) {
		// TODO Auto-generated method stub
		if(chatData.getAllUsers().contains(user)) chatData.getAllUsers().remove(user);
		else chatData.getAllUsers().add(user);
		userSync.syncWithClient(user);
	}

	@Override
	public List<Host> getAllHosts() {
		// TODO Auto-generated method stub
		return chatData.getHosts();
	}

	@Override
	public List<User> getAllUsers() {
		// TODO Auto-generated method stub
		return chatData.getAllUsers();
	}

	@Override
	public List<User> getAllUsers(Host host) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void publish(Message message) {
		TopicConnection connection;
		if(message.getTo()==null || message.getTo().getHost().equals(chatData.getLocalHost())) {
			try {
				connection = (TopicConnection)connectionFactory.createConnection("guest", "guestguest");
		        TopicSession session = connection.createTopicSession(false,
		                Session.AUTO_ACKNOWLEDGE);
				connection.start();
				// create and publish a message
				ObjectMessage msg = session.createObjectMessage();
				msg.setObject(message);
				MessageProducer producer = session.createProducer(topic);
				producer.send(msg);
				producer.close();
				connection.stop();
				connection.close();
				session.close();
				System.out.println(chatData.getHosts().toString());
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
